package com.gzhryc.shared_device.common.payment.services;

import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import com.alipay.api.response.AlipayFundAuthOperationDetailQueryResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.gzhryc.common.StringTools;
import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.json.JsonTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.jdbc.Conditions;
import com.gzhryc.jdbc.MultiDBTools;
import com.gzhryc.pay.adaptation.alipay.enums.EAliPayNormalTradeState;
import com.gzhryc.pay.adaptation.alipay.enums.EAlipayAdvanceOrderState;
import com.gzhryc.pay.adaptation.alipay.msg.advance_pay.AlipayAdvancePayConfirmNotify;
import com.gzhryc.pay.adaptation.alipay.msg.advance_pay.AlipayAdvancePayFinishNotify;
import com.gzhryc.pay.adaptation.alipay.msg.normal.AlipayNormalPayNotify;
import com.gzhryc.pay.enums.TradeType;
import com.gzhryc.shared_device.base.enums.EPayState;
import com.gzhryc.shared_device.common.payment.dao.AlipayOrderDao;
import com.gzhryc.shared_device.common.payment.dao.db.AlipayAbnormalPayOrder;
import com.gzhryc.shared_device.common.payment.dao.db.AlipayOrder;
import com.gzhryc.shared_device.common.payment.dao.db.WXPayOrder;
import com.gzhryc.shared_device.common.payment.dao.enums.AlipayAbnormalPayOrderEnum;
import com.gzhryc.shared_device.common.payment.dao.enums.AlipayConfigEnum;
import com.gzhryc.shared_device.common.payment.services.dto.AlipayOrderSearch;

public class AlipayOrderService {

	static Logger log = Logger.getLogger(AlipayOrderService.class);

    public static AlipayOrderService self(Date date) {
        return MultiDBTools.getService(AlipayOrderService.class, date);
    }

    public static AlipayOrderService self(String jdbcKey,Date date) {
        return MultiDBTools.getService(jdbcKey, AlipayOrderService.class, date);
    }

    AlipayOrderDao dao;

    public AlipayOrderService(String jdbcKey,Date date) {
        dao = new AlipayOrderDao(jdbcKey,date);
    }

    public List<AlipayOrder> findBySearch(AlipayOrderSearch search, Integer pageNo, Integer pageLimit){
        Conditions conditions = dao.buildConditions(search);
        conditions.desc("createDate");

        try {
            return dao.findByCondition(conditions,pageNo,pageLimit);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public List<AlipayOrder> findByBusinessTradeNo(String businessTradeNo){
        if(StringTools.isNotBlank(businessTradeNo)){
            Conditions conditions = new Conditions(AlipayOrder.class);
            conditions.and().is("businessTradeNo",businessTradeNo);

            try {
                return dao.findByCondition(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return null;
    }

    public Long countBySearch(AlipayOrderSearch search){
        Conditions conditions = dao.buildConditions(search);
        try {
            return dao.count(conditions);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return 0L;
    }

    public AlipayOrder getByTradeNo(String tradeNo){
        try {
            return dao.getById(tradeNo);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }
    
    public AlipayOrder getLastByBusinessTradeNo(String businessTradeNo) {
    	if(StringTools.isNotBlank(businessTradeNo)) {
    		Conditions condition = new Conditions(AlipayOrder.class);
    		condition.and().is("businessTradeNo", businessTradeNo);
	        try {
	            return dao.get(condition);
	        } catch (SQLException e) {
	            log.error(e.getMessage(),e);
	        }
    	}
        return null;
    }
    
    public AlipayOrder getByExternalTradeNo(String externalTradeNo){
    	if(StringTools.isNotBlank(externalTradeNo)) {
    		Conditions condition = new Conditions(AlipayOrder.class);
    		condition.and().is("externalTradeNo", externalTradeNo);
	        try {
	            return dao.get(condition);
	        } catch (SQLException e) {
	            log.error(e.getMessage(),e);
	        }
    	}
        return null;
    }
    
    public boolean closeWaitPay(AlipayOrder payOrder) {
    	return false;
    }

    public int payResult(AlipayOrder payOrder, AlipayNormalPayNotify notify) throws LogicException {
        //签名验证
        if(notify.isTrue()) {
        	// 检查金额
            if (!payOrder.getPayMoney().equals(notify.getMoney())) {
                // throw new LogicException("支付金额不正确");
                log.error("支付宝支付金额不正确，回调信息：" + JsonTools.toJson(notify));
            }
            
	        try {
	            payOrder.setExternalTradeNo(notify.getExternalTradeNo());
	            payOrder.setExternalContent(JsonTools.toJson(notify));
	            payOrder.setReceiptMoney(notify.getMoney());
	            payOrder.setPayDate(new Date());
	            if (EAliPayNormalTradeState.TRADE_SUCCESS.name().equals(notify.getTradeStatus())) {
	                payOrder.setPayStatus(EPayState.Success.index());
	            } else {
	                payOrder.setPayStatus(EPayState.Fail.index());
	            }
	            if(dao.insert(payOrder) > 0){
	                if(EPayState.Success.index().equals(payOrder.getPayStatus())){
	                    return 1;
	                }else {
	                    return 0;
	                }
	            }
	        } catch (SQLException e) {
	            log.error("支付宝支付订单处理错误，" + e.getMessage(), e);
	        }
        }else {
        	//记录异常
        	AlipayAbnormalPayOrder timeoutPayOrder = null;
            try {
            	timeoutPayOrder = new AlipayAbnormalPayOrder();
                timeoutPayOrder.setTradeNo(notify.getTradeNo());
                timeoutPayOrder.setExternalTradeNo(notify.getExternalTradeNo());
                timeoutPayOrder.setType(AlipayAbnormalPayOrderEnum.Type.ValidationFailed.index());
                timeoutPayOrder.setAppType(AlipayConfigEnum.AppType.alixcx.index());
                timeoutPayOrder.setAppId(notify.getAppId());
                timeoutPayOrder.setPayerId(notify.getPayerId());
                timeoutPayOrder.setBusinessAccount(notify.getSellerId());
                timeoutPayOrder.setTradeType(TradeType.Normal.name());
                timeoutPayOrder.setPayMoney(notify.getMoney());
                timeoutPayOrder.setExternalContent(notify.getJson());
                if (EAliPayNormalTradeState.TRADE_SUCCESS.name().equals(notify.getTradeStatus())) {
                    timeoutPayOrder.setPayStatus(EPayState.Success.index());
                } else {
                    timeoutPayOrder.setPayStatus(EPayState.Fail.index());
                }
                timeoutPayOrder.setCreateDate(new Date());
                AlipayAbnormalPayOrderService.self().add(timeoutPayOrder);
            } catch (Exception e) {
            	log.error("支付宝支付订单签名失败，订单信息：{{0:json}}", timeoutPayOrder);
            	log.error(e.getMessage(), e);
            }
        	
        }
        return -1;
    }
    
    /**
     * 用户免押支付
     * @param payOrder
     * @param notify
     * @return
     * @throws LogicException
     */
    public int payResult(AlipayOrder payOrder, AlipayAdvancePayFinishNotify notify) throws LogicException {
        try {
        	AlipayOrder updateEntity = new AlipayOrder();
			updateEntity.setTradeNo(payOrder.getTradeNo());
			updateEntity.setExternalTradeNo(notify.getExternalTradeNo());
			updateEntity.setExternalContent(notify.getJson());
			updateEntity.setPayMoney(notify.getMoney());
			updateEntity.setPayDate(new Date());
			updateEntity.setPayStatus(EPayState.Fail.index());
            if (EAlipayAdvanceOrderState.FINISH.name().equals(notify.getTradeStatus())){
            	updateEntity.setPayStatus(EPayState.Success.index());
			}

            if(dao.updateNotNull(updateEntity) > 0){
            	payOrder.setExternalTradeNo(updateEntity.getExternalTradeNo());
            	payOrder.setExternalContent(updateEntity.getExternalContent());
            	payOrder.setPayMoney(updateEntity.getPayMoney());
            	payOrder.setPayDate(updateEntity.getPayDate());
            	payOrder.setPayStatus(updateEntity.getPayStatus());
                if(EPayState.Success.index().equals(payOrder.getPayStatus())){
                    return 1;
                }else {
                    return 0;
                }
            }
        } catch (SQLException e) {
            log.error("支付宝免押订单处理错误，" + e.getMessage(), e);
        }
        return -1;
    }
    
    public int payResult(AlipayOrder payOrder, AlipayAdvancePayConfirmNotify notify) throws LogicException {
        try {
            payOrder.setExternalTradeNo(notify.getExternalTradeNo());
            payOrder.setExternalContent(notify.getJson());
            payOrder.setPayDate(new Date());
            payOrder.setPayStatus(EPayState.Close.index());
            if (EAlipayAdvanceOrderState.AUTHORIZED.name().equals(notify.getStatus())) {
            	payOrder.setPayStatus(EPayState.Confirm.index());
			}
            if(dao.insert(payOrder) > 0){
                if(EPayState.Confirm.index().equals(payOrder.getPayStatus())){
                    return 1;
                }else {
                    return 0;
                }
            }
        } catch (SQLException e) {
            log.error("支付宝免押订单处理错误，" + e.getMessage(), e);
        }
        return -1;
    }

 
    public WXPayOrder synExternalPayOrder(AlipayOrder payOrder,AlipayTradeQueryResponse externalPayOrder)throws LogicException{
        return null;
    }
    
    public WXPayOrder synExternalPayOrder(AlipayOrder payOrder,AlipayFundAuthOperationDetailQueryResponse externalPayOrder)throws LogicException{
    	return null;
    }
}
